#include "display_ctrl.h"
#include "display_interface.h"
#include "string.h"
#include "font_mngr.h"
#include "arabic_reshaper.h"
#include "common/common.h"
#include "arabic_reshaper.h"
#include "utf8_to_unicode.h"
#include "arm_math.h"
#define BIG_ROW_HEIGHT 8
typedef struct __point_info_t
{
    uint16_t *point;
    int x;
    int y;
    int i;
    int j;
    int height;
    uint16_t color;
    void const *draw_ext_para;
} point_info_t;
static uint16_t get_multiply_color(uint16_t color1, uint16_t color2);
uint8_t get_num_digit(int num)
{
    uint8_t digit = 0;
    //负号
    if (num < 0)
    {
        digit = 1;
        num = -num;
    }

    do
    {
        digit++;
        num /= 10;
    } while (num);

    return digit;
}
static uint16_t get_color_by_gray_level(uint16_t color, uint8_t gray_level)
{
    uint8_t red, green, blue;

    blue = ((color & 0x1F) * gray_level) / 31;
    green = (((color >> 5) & 0x3F) * gray_level) / 31;
    red = (((color >> 11) & 0x1F) * gray_level) / 31;

    return (red << 11) | (green << 5) | (blue);
}

typedef void (*draw_point_callback)(point_info_t const *point_info_t);
static void draw_on_chip_image_base(int x, int y, uint8_t const *const image, draw_point_callback callback, void const *draw_ext_para)
{
#define DISP_POINT_INFO_CALL                                                                                                                                                                           \
    do                                                                                                                                                                                                 \
    {                                                                                                                                                                                                  \
        point_info_t const info = {                                                                                                                                                                    \
            .point = &p_disp_buff[j],                                                                                                                                                                  \
            .x = j + x,                                                                                                                                                                                \
            .y = i + y,                                                                                                                                                                                \
            .i = j,                                                                                                                                                                                    \
            .j = i,                                                                                                                                                                                    \
            .height = height,                                                                                                                                                                          \
            .color = last_color,                                                                                                                                                                       \
            .draw_ext_para = draw_ext_para,                                                                                                                                                            \
        };                                                                                                                                                                                             \
        callback(&info);                                                                                                                                                                               \
    } while (0)
    uint8_t const *p_user_image = image;
    uint16_t width = 0;
    uint16_t height = 0;
    uint16_t color_number = 0;
    uint16_t *color_tab = (uint16_t *)(p_user_image + 6);
    width = p_user_image[0] + (p_user_image[1] << 8);
    height = p_user_image[2] + (p_user_image[3] << 8);
    color_number = p_user_image[4] + (p_user_image[5] << 8);
    p_user_image += color_number * 2 + 6; //指向数据

    uint16_t last_color = color_tab[0];
    uint16_t same_color_cnt = 0;
    uint16_t image_data_index = 0;
    uint8_t addr_out_flag = 0;

    //判断和要显示的区域是否有重叠区域
    if ((disp_ctrl.area_start_y > (y + height - 1)) || (disp_ctrl.area_end_y < y))
    {
        return;
    }
    uint16_t *p_disp_buff = 0;
    uint8_t icon_start_y = 0;
    uint8_t icon_end_y = 0; //标记ICON需要显示的范围
    if (y >= disp_ctrl.area_start_y)
    {
        p_disp_buff = disp_ctrl.disp_buff[disp_ctrl.p_buff_flag] + (y - disp_ctrl.area_start_y) * OLED_SIZE_X + x; //指向要填充的位置
        icon_start_y = 0;
    }
    else
    {
        p_disp_buff = disp_ctrl.disp_buff[disp_ctrl.p_buff_flag] + x; //指向要填充的位置
        icon_start_y = disp_ctrl.area_start_y - y;
    }
    if (disp_ctrl.area_end_y >= (y + height - 1))
    {
        icon_end_y = height - 1;
    }
    else
    {
        icon_end_y = disp_ctrl.area_end_y - y;
    }

    //依次填充数据
    if (color_number <= 127)
    {
        //计算跳过的数据
        uint16_t invalid_cnt = icon_start_y * width;
        uint8_t same_color_cnt_flag = 0;
        while (invalid_cnt > 0)
        {
            if (p_user_image[image_data_index] & 0x80)
            {
                same_color_cnt = (p_user_image[image_data_index] & 0x7F);
                if (invalid_cnt >= same_color_cnt)
                {
                    invalid_cnt -= same_color_cnt;
                }
                else
                {
                    same_color_cnt -= invalid_cnt;
                    invalid_cnt = 0;
                    same_color_cnt_flag = 1;
                }
            }
            else
            {
                invalid_cnt--;
                last_color = color_tab[p_user_image[image_data_index]];
            }
            image_data_index++;
        }
        if (same_color_cnt_flag == 0)
        {
            same_color_cnt = 0;
        }
        for (uint16_t i = icon_start_y; i <= icon_end_y; i++)
        {
            addr_out_flag = 0;
            for (uint16_t j = 0; j < width; j++)
            {
                if (((j + x) < 0) || ((j + x) >= OLED_SIZE_X)) //地址溢出的不处理
                {
                    addr_out_flag |= 2;
                }
                else
                {
                    addr_out_flag &= ~2;
                }
                if (same_color_cnt) //继续相同颜色的填充
                {
                    same_color_cnt--;
                    if (addr_out_flag == 0)
                    {
                        DISP_POINT_INFO_CALL;
                    }
                    continue;
                }

                if (p_user_image[image_data_index] & 0x80)
                {
                    if (addr_out_flag == 0)
                    {
                        DISP_POINT_INFO_CALL;
                    }
                    same_color_cnt = (p_user_image[image_data_index] & 0x7F) - 1;
                }
                else
                {
                    last_color = color_tab[p_user_image[image_data_index]];
                    if (addr_out_flag == 0)
                    {
                        DISP_POINT_INFO_CALL;
                    }
                }
                image_data_index++;
            }
            p_disp_buff += OLED_SIZE_X;
        }
    }
    else
    {
        //计算跳过的数据
        uint16_t invalid_cnt = icon_start_y * width;
        uint8_t same_color_cnt_flag = 0;
        while (invalid_cnt > 0)
        {
            if (p_user_image[image_data_index] == 0xFF)
            {
                image_data_index++;
                same_color_cnt = (p_user_image[image_data_index]);
                if (invalid_cnt >= same_color_cnt)
                {
                    invalid_cnt -= same_color_cnt;
                }
                else
                {
                    same_color_cnt -= invalid_cnt;
                    invalid_cnt = 0;
                    same_color_cnt_flag = 1;
                }
            }
            else
            {
                invalid_cnt--;
                last_color = color_tab[p_user_image[image_data_index]];
            }
            image_data_index++;
        }
        if (same_color_cnt_flag == 0)
        {
            same_color_cnt = 0;
        }
        for (uint16_t i = icon_start_y; i <= icon_end_y; i++)
        {
            addr_out_flag = 0;
            for (uint16_t j = 0; j < width; j++)
            {
                if (((j + x) < 0) || ((j + x) >= OLED_SIZE_X)) //地址溢出的不处理
                {
                    addr_out_flag |= 2;
                }
                else
                {
                    addr_out_flag &= ~2;
                }
                if (same_color_cnt) //继续相同颜色的填充
                {
                    same_color_cnt--;
                    if (addr_out_flag == 0)
                    {
                        DISP_POINT_INFO_CALL;
                    }
                    continue;
                }

                if (p_user_image[image_data_index] == 0xFF)
                {
                    if (addr_out_flag == 0)
                    {
                        DISP_POINT_INFO_CALL;
                    }
                    image_data_index++;
                    same_color_cnt = (p_user_image[image_data_index]) - 1;
                }
                else
                {
                    last_color = color_tab[p_user_image[image_data_index]];
                    if (addr_out_flag == 0)
                    {
                        DISP_POINT_INFO_CALL;
                    }
                }
                image_data_index++;
            }
            p_disp_buff += OLED_SIZE_X;
        }
    }
}
void disp_show_font_string_utf8_mid(uint8_t y, const char *str, uint8_t reserve_size)
{
    int16_t align_type = align_type_right;
    uint8_t buff[120] = {0};
    utf8_string_to_unicode_string((const uint8_t *)str, buff, sizeof(buff));
    draw_off_chip_string(0, y, 79, y + 16 - 1, (uint16_t const *)buff, 0, &align_type);
}

void disp_show_user_string_middle(uint8_t start_x, int width, uint8_t start_y, char *p_string, uint8_t const *(*get_bmp)(char c))
{
    // #warning debug
    int16_t align_type = align_type_right;
    uint8_t buff[120] = {0};
    utf8_string_to_unicode_string((const uint8_t *)p_string, buff, sizeof(buff));
    draw_off_chip_string(0, 10, 79, 50, (uint16_t const *)buff, 0, &align_type);
}

void draw_on_chip_image_callback(point_info_t const *point_info_t)
{
    *point_info_t->point = point_info_t->color;
}
void draw_on_chip_image_filter_color_callback(point_info_t const *point_info_t)
{
    *point_info_t->point = get_filter_color(point_info_t->color, *point_info_t->point);
}
void draw_on_chip_image_multiply_color_callback(point_info_t const *point_info_t)
{
    *point_info_t->point = get_multiply_color(point_info_t->color, *point_info_t->point);
}

void draw_on_chip_image(int x, int y, uint8_t const *const image)
{
    draw_on_chip_image_ext(x, y, image, draw_type_normal);
}
void draw_on_chip_image_ext(int x, int y, uint8_t const *const image, draw_type_t type)
{
    switch (type)
    {
    case draw_type_normal:
        draw_on_chip_image_base(x, y, image, draw_on_chip_image_callback, 0);
        break;
    case draw_type_filter_color:
        draw_on_chip_image_base(x, y, image, draw_on_chip_image_filter_color_callback, 0);
        break;
    case draw_type_multiply:
        draw_on_chip_image_base(x, y, image, draw_on_chip_image_multiply_color_callback, 0);
        break;
    }
}

void draw_on_chip_gray_image_callback(point_info_t const *point_info_t)
{
#pragma diag_suppress = 767
    uint16_t color_base = (uint16_t)(point_info_t->draw_ext_para);
#pragma diag_warning = 767
    // *point_info_t->point = get_color_by_gray_level(color_base, point_info_t->color & 0x1F);
    *point_info_t->point = get_color_by_gray_level(color_base, point_info_t->color & 0x1F);
    //*point_info_t->point = point_info_t->color;
}

void draw_on_chip_gray_image(int x, int y, uint8_t const *const image, uint16_t color_base)
{
    draw_on_chip_image_base(x, y, image, draw_on_chip_gray_image_callback, (void const *)color_base);
}
void draw_on_chip_gray_image_filter_color_callback(point_info_t const *point_info_t)
{
#pragma diag_suppress = 767
    uint16_t color_base = (uint16_t)(point_info_t->draw_ext_para);
#pragma diag_warning = 767
    *point_info_t->point = get_filter_color(get_color_by_gray_level(color_base, point_info_t->color & 0x1F), *point_info_t->point);

    //*point_info_t->point = point_info_t->color;
}
void draw_on_chip_gray_image_filter_color(int x, int y, uint8_t const *const image, uint16_t color_base)
{
    draw_on_chip_image_base(x, y, image, draw_on_chip_gray_image_filter_color_callback, (void const *)color_base);
}

void draw_on_chip_gif_array(int x, int y, uint8_t const *const *const image_array, uint32_t array_size)
{
    draw_on_chip_image(x, y, image_array[disp_ctrl.auto_refresh_count % array_size]);
}
void draw_on_chip_gif_array_filter_color(int x, int y, uint8_t const *const *const image_array, uint32_t array_size)
{
    draw_on_chip_image_ext(x, y, image_array[disp_ctrl.auto_refresh_count % array_size], draw_type_filter_color);
}
void draw_on_chip_unzip_gif_array(int x, int y, uint8_t const *const *const image_array, uint32_t array_size)
{
    draw_on_chip_unzip_image(x, y, image_array[disp_ctrl.auto_refresh_count % array_size]);
}
void draw_on_chip_unzip_image_with_forecolor(int x, int y, uint8_t const *const binary_image, uint16_t forecolor)
{
    int index = 0;
    int w = binary_image[0];
    int h = binary_image[1];

    for (int y_idx = 0; y_idx < h; y_idx++)
    {
        for (int x_idx = 0; x_idx < w; x_idx++)
        {
            index = 2 + y_idx / BIG_ROW_HEIGHT * w + x_idx; // 从原图buffer中取数据，起点不一定为(0, 0)
            if (binary_image[index] & (0x80 >> (y_idx % BIG_ROW_HEIGHT)))
            {
                draw_point(x + x_idx, y + y_idx, forecolor);
            }
            else
            {
                // draw_point(x + x_idx, y + y_idx, backcolor);
            }
        }
    }
}
void draw_on_chip_unzip_image(int x, int y, uint8_t const *const binary_image)
{
    draw_on_chip_unzip_image_with_forecolor(x, y, binary_image, RGB565_COLOR_WHITE);
    // int index = 0;
    // int w = binary_image[0];
    // int h = binary_image[1];

    // for (int y_idx = 0; y_idx < h; y_idx++)
    // {
    //     for (int x_idx = 0; x_idx < w; x_idx++)
    //     {
    //         index = 2 + y_idx / BIG_ROW_HEIGHT * w + x_idx; // 从原图buffer中取数据，起点不一定为(0, 0)
    //         if (binary_image[index] & (0x80 >> (y_idx % BIG_ROW_HEIGHT)))
    //         {
    //             draw_point(x + x_idx, y + y_idx, RGB565_COLOR_WHITE);
    //         }
    //         else
    //         {
    //             // draw_point(x + x_idx, y + y_idx, backcolor);
    //         }
    //     }
    // }
}
void draw_on_chip_gray_gif_array(int x, int y, uint8_t const *const *const image_array, uint32_t array_size, uint16_t color_base)
{
    draw_on_chip_gray_image(x, y, image_array[disp_ctrl.auto_refresh_count % array_size], color_base);
}
void draw_on_chip_gray_gif_array_filter_color(int x, int y, uint8_t const *const *const image_array, uint32_t array_size, uint16_t color_base)
{
    draw_on_chip_gray_image_filter_color(x, y, image_array[disp_ctrl.auto_refresh_count % array_size], color_base);
}

void draw_rectangle_empty(int x0, int y0, int x1, int y1, uint16_t color)
{
    if ((disp_ctrl.area_start_y > (y1)) || (disp_ctrl.area_end_y < y0))
    {
        return;
    }
    draw_horizontal_line(x0, x1, y0, color);
    draw_horizontal_line(x0, x1, y1, color);
    draw_vertical_line(x0, y0, y1, color);
    draw_vertical_line(x1, y0, y1, color);
}

void draw_rectangle(int x1, int y1, int x2, int y2, uint16_t color)
{
    if ((disp_ctrl.area_start_y > (y2)) || (disp_ctrl.area_end_y < y1))
    {
        return;
    }

    uint16_t *p_disp_buff;
    uint8_t icon_start_y, icon_end_y; //标记ICON需要显示的范围
    if (y1 >= disp_ctrl.area_start_y)
    {
        p_disp_buff = disp_ctrl.disp_buff[disp_ctrl.p_buff_flag] + (y1 - disp_ctrl.area_start_y) * OLED_SIZE_X; //指向要填充的位置
        icon_start_y = 0;
    }
    else
    {
        p_disp_buff = disp_ctrl.disp_buff[disp_ctrl.p_buff_flag]; //指向要填充的位置
        icon_start_y = disp_ctrl.area_start_y - y1;
    }
    if (disp_ctrl.area_end_y >= (y2))
    {
        icon_end_y = y2 - y1;
    }
    else
    {
        icon_end_y = disp_ctrl.area_end_y - y1;
    }

    for (uint8_t i = icon_start_y; i <= icon_end_y; i++)
    {
        for (uint8_t j = x1; j <= x2; j++)
        {
            *(p_disp_buff + j) = color;
        }
        p_disp_buff += OLED_SIZE_X;
    }
}
typedef struct
{
    uint8_t b : 5; // 大端先发送，R4R3R2R1R0G5G4G3G2G1G0B4B3B2B1B0
    uint8_t gl : 3;
    uint8_t gh : 3;
    uint8_t r : 5;
} rgb565_t;

static uint16_t get_gradients(uint16_t begin, uint16_t end, uint8_t current, uint8_t total)
{
    rgb565_t color_begin = {0};
    rgb565_t color_end = {0};
    rgb565_t ret_color = {0};
    uint16_t u16_color = 0;
    uint8_t green = 0;

    memcpy(&color_begin, &begin, sizeof(uint16_t));
    memcpy(&color_end, &end, sizeof(uint16_t));

    ret_color.r = color_begin.r + (color_end.r - color_begin.r) * current / total;
    ret_color.b = color_begin.b + (color_end.b - color_begin.b) * current / total;

    green = (color_begin.gh * 8 + color_begin.gl) + ((color_end.gh * 8 + color_end.gl) - (color_begin.gh * 8 + color_begin.gl)) * current / total;
    ret_color.gh = green / 8;
    ret_color.gl = green % 8;

    memcpy(&u16_color, &ret_color, sizeof(uint16_t));
    return u16_color;
}

void draw_point(int x, int y, uint16_t color)
{
    if ((y >= disp_ctrl.area_start_y) && (y <= disp_ctrl.area_end_y))
    {
        disp_ctrl.disp_buff[disp_ctrl.p_buff_flag][(y - disp_ctrl.area_start_y) * OLED_SIZE_X + x] = color;
    }
}
typedef struct __draw_on_chip_gradients_image_params_t
{
    uint16_t forecolor_start;
    uint16_t forecolor_end;
} draw_on_chip_gradients_image_params_t;
void draw_on_chip_gradients_image_callback(point_info_t const *point_info_t)
{
    draw_on_chip_gradients_image_params_t const *params = point_info_t->draw_ext_para;
    int color_base = get_gradients(params->forecolor_start, params->forecolor_end, point_info_t->j, point_info_t->height);
    *point_info_t->point = get_color_by_gray_level(color_base, point_info_t->color & 0x1F);
}

void draw_on_chip_gradients_image(int x, int y, uint8_t const *binary_image, uint16_t forecolor_start, uint16_t forecolor_end)
{
    draw_on_chip_gradients_image_params_t params = {
        .forecolor_start = forecolor_start,
        .forecolor_end = forecolor_end,
    };

    draw_on_chip_image_base(x, y, binary_image, draw_on_chip_gradients_image_callback, &params);
}
void draw_on_chip_unzip_gradients_image(int x, int y, uint8_t const *binary_image, uint16_t forecolor_start, uint16_t forecolor_end, uint16_t backcolor)
{
    int w = binary_image[0];
    int h = binary_image[1];
    int img_x_index = 0;
    int img_y_index = 0;
    uint16_t color = 0;
    int draw_y = 0;
    for (img_y_index = 0; img_y_index < h; img_y_index++)
    {
        draw_y = y + img_y_index;
        if ((draw_y >= disp_ctrl.area_start_y) && (draw_y <= disp_ctrl.area_end_y))
        {
            for (img_x_index = 0; img_x_index < w; img_x_index++)
            {
                if (binary_image[2 + img_y_index / 8 * w + img_x_index] & (0x80 >> (img_y_index % 8)))
                {
                    color = get_gradients(forecolor_start, forecolor_end, img_y_index, h);
                    draw_point(x + img_x_index, y + img_y_index, color);
                }
                else
                {
                    draw_point(x + img_x_index, y + img_y_index, backcolor);
                }
            }
        }
    }
}

/**
 * @brief
 *
 * @param num
 * @param x
 * @param y
 * @param num_image_array
 * @param num_width
 * @param num_interval
 * @return int draw完后的下一个像素
 */
int draw_on_chip_image_num_with_digits(int num, int num_digits, int x, int y, uint8_t const *const *const num_image_array, int num_width, int num_interval, draw_type_t type)
{
    int num_height = num_image_array[0][1];
    int width = num_width * num_digits + num_interval * (num_digits - 1);
    int end_draw = x + width;
    int draw_x = x + width - num_width;
    int num_temp = num;
    if (num_temp < 0)
    {
        num_temp = -num_temp;
    }
    for (int i = 0; i < num_digits; i++)
    {
        draw_on_chip_image_ext(draw_x, y, num_image_array[num_temp % 10], type);
        draw_x -= num_width + num_interval;
        num_temp /= 10;
    }
    if (num < 0)
    {
        draw_horizontal_line(draw_x, draw_x + num_width - 1, y + num_height / 2, RGB565_COLOR_WHITE);
    }
    return end_draw;
}

/**
 * @brief
 *
 * @param num
 * @param x
 * @param y
 * @param num_image_array
 * @param num_width
 * @param num_interval
 * @return int draw完后的下一个像素
 */
int draw_on_chip_image_num(int num, int x, int y, uint8_t const *const *const num_image_array, int num_width, int num_interval, draw_type_t type)
{
    int num_digits = get_num_digit(num);
    return draw_on_chip_image_num_with_digits(num, num_digits, x, y, num_image_array, num_width, num_interval, type);
}
/**
 * @brief
 *
 * @param num
 * @param x0
 * @param y0
 * @param x1
 * @param y1
 * @param num_image_array
 * @param num_width
 * @param num_interval
 * @return int  draw完后的下一个像素
 */
int draw_on_chip_image_num_center(int num, int x0, int y0, int x1, int y1, uint8_t const *const *const num_image_array, int num_width, int num_interval, draw_type_t type)
{
    int num_digits = get_num_digit(num);
    int width = num_width * num_digits + num_interval * (num_digits - 1);
    int x_start = x0 + (x1 + 1 - x0 - width) / 2;
    return draw_on_chip_image_num(num, x_start, y0, num_image_array, num_width, num_interval, type);
}

void draw_horizontal_line(int x0, int x1, int y, uint16_t color)
{
    if (y < disp_ctrl.area_start_y || y > disp_ctrl.area_end_y)
    {
        return;
    }
    for (int i = x0; i <= x1; i++)
    {
        draw_point(i, y, color);
    }
}
void draw_vertical_line(int x, int y0, int y1, uint16_t color)
{
    if (y1 < disp_ctrl.area_start_y || y0 > disp_ctrl.area_end_y)
    {
        return;
    }
    for (int i = y0; i <= y1; i++)
    {
        draw_point(x, i, color);
    }
}
uint16_t get_filter_color(uint16_t color1, uint16_t color2)
{
    uint16_t red = 0;
    uint16_t green = 0;
    uint16_t blue = 0;
    blue = 31 - ((31 - RGB565_GET_COLOR_B(color1)) * (31 - RGB565_GET_COLOR_B(color2))) / 31;
    green = 63 - ((63 - RGB565_GET_COLOR_G(color1)) * (63 - RGB565_GET_COLOR_G(color2))) / 63;
    red = 31 - ((31 - RGB565_GET_COLOR_R(color1)) * (31 - RGB565_GET_COLOR_R(color2))) / 31;
    if (blue > 31)
    {
        blue = 31;
    }
    if (green > 63)
    {
        green = 63;
    }
    if (red > 31)
    {
        red = 31;
    }
    uint16_t ret = (red << 11) | (green << 5) | (blue);
    return ret;
}
//uint16_t get_multiply_color(uint16_t color1, uint16_t color2)
//{
//    if (color1 == 0xffdf)
//    {
//        color1 = 0xffff;
//    }
//    uint16_t red = 0;
//    uint16_t green = 0;
//    uint16_t blue = 0;
//    red = RGB565_GET_COLOR_R(color1) * RGB565_GET_COLOR_R(color2) / 31;
//    green = RGB565_GET_COLOR_G(color1) * RGB565_GET_COLOR_G(color2) / 63;
//    blue = RGB565_GET_COLOR_B(color1) * RGB565_GET_COLOR_B(color2) / 31;
//    if (blue > 31)
//    {
//        blue = 31;
//    }
//    if (green > 63)
//    {
//        green = 63;
//    }
//    if (red > 31)
//    {
//        red = 31;
//    }
//    uint16_t ret = (red << 11) | (green << 5) | (blue);
//    return ret;
//}
// color transparency_by_white false = 黑色表示透明，白色表示完全
static uint16_t transparency_anti_aliasing(uint16_t color, uint16_t back, uint16_t solid_colour, bool transparency_by_white)
{
    // uint16_t red = 0;
    // uint16_t green = 0;
    // uint16_t blue = 0;
    // float transparency[3] = {0.f, 0.f, 0.f};
    uint16_t const color_rgb[3] = {RGB565_GET_COLOR_R(color), RGB565_GET_COLOR_G(color), RGB565_GET_COLOR_B(color)};
    uint16_t const solid_rgb[3] = {RGB565_GET_COLOR_R(solid_colour), RGB565_GET_COLOR_G(solid_colour), RGB565_GET_COLOR_B(solid_colour)};
    uint16_t const max_rgb[3] = {31, 63, 31};
    uint16_t result_rgb[3] = {0};
    int transparency_index = 0; //选定RGB最大的那个数，来做透明度
    {
        uint16_t max_rgb = 0;
        uint16_t min_rgb = 0xFFFF;
        for (int i = 0; i < 3; i++)
        {
            if (transparency_by_white)
            {
                if (min_rgb > solid_rgb[i])
                {
                    min_rgb = solid_rgb[i];
                    transparency_index = i;
                }
            }
            else
            {
                if (max_rgb < solid_rgb[i])
                {
                    max_rgb = solid_rgb[i];
                    transparency_index = i;
                }
            }
        }
    }
    float transparency = 0.f;
    if (transparency_by_white)
    {
        if (color_rgb[transparency_index] < solid_rgb[transparency_index])
        {
            transparency = 1.f;
        }
        else if (solid_rgb[transparency_index] != max_rgb[transparency_index])
        {
            transparency = ((float)(max_rgb[transparency_index] - color_rgb[transparency_index])) / (max_rgb[transparency_index] - solid_rgb[transparency_index]);
        }
    }
    else
    {
        if (color_rgb[transparency_index] > solid_rgb[transparency_index])
        {
            transparency = 1.f;
        }
        else if (solid_rgb[transparency_index] != 0)
        {
            transparency = (float)color_rgb[transparency_index] / solid_rgb[transparency_index];
        }
    }
    uint16_t const back_rgb[3] = {RGB565_GET_COLOR_R(back), RGB565_GET_COLOR_G(back), RGB565_GET_COLOR_B(back)};
    for (int i = 0; i < 3; i++)
    {
        result_rgb[i] = back_rgb[i] + ((int)solid_rgb[i] - back_rgb[i]) * transparency;
        if (result_rgb[i] > max_rgb[i])
        {
            result_rgb[i] = max_rgb[i];
        }
    }
    uint16_t ret = (result_rgb[0] << 11) | (result_rgb[1] << 5) | (result_rgb[2]);
    return ret;
    // float transparency_max = 0.f;
    // if (transparency_by_white)
    // {
    //     if (RGB565_GET_COLOR_R(color) < RGB565_GET_COLOR_R(solid_colour))
    //     {
    //         transparency[0] = 1.f;
    //     }
    //     else if (RGB565_GET_COLOR_R(solid_colour) != 31)
    //     {
    //         transparency[0] = (31 - (float)RGB565_GET_COLOR_R(color)) / (31 - RGB565_GET_COLOR_R(solid_colour));
    //     }

    //     if (RGB565_GET_COLOR_G(color) < RGB565_GET_COLOR_G(solid_colour))
    //     {
    //         transparency[1] = 1.f;
    //     }
    //     else if (RGB565_GET_COLOR_G(solid_colour) != 63)
    //     {
    //         transparency[1] = (63 - (float)RGB565_GET_COLOR_G(color)) / (63 - RGB565_GET_COLOR_G(solid_colour));
    //     }

    //     if (RGB565_GET_COLOR_B(color) < RGB565_GET_COLOR_B(solid_colour))
    //     {
    //         transparency[2] = 1.f;
    //     }
    //     else if (RGB565_GET_COLOR_B(solid_colour) != 31)
    //     {
    //         transparency[2] = (31 - (float)RGB565_GET_COLOR_B(color)) / (31 - RGB565_GET_COLOR_B(solid_colour));
    //     }
    // }
    // else
    // {
    //     if (RGB565_GET_COLOR_R(color) > RGB565_GET_COLOR_R(solid_colour))
    //     {
    //         transparency[0] = 1.f;
    //     }
    //     else if (RGB565_GET_COLOR_R(solid_colour) != 0)
    //     {
    //         transparency[0] = (float)RGB565_GET_COLOR_R(color) / RGB565_GET_COLOR_R(solid_colour);
    //     }

    //     if (RGB565_GET_COLOR_G(color) > RGB565_GET_COLOR_G(solid_colour))
    //     {
    //         transparency[1] = 1.f;
    //     }
    //     else if (RGB565_GET_COLOR_G(solid_colour) != 0)
    //     {
    //         transparency[1] = (float)RGB565_GET_COLOR_G(color) / RGB565_GET_COLOR_G(solid_colour);
    //     }

    //     if (RGB565_GET_COLOR_B(color) > RGB565_GET_COLOR_B(solid_colour))
    //     {
    //         transparency[2] = 1.f;
    //     }
    //     else if (RGB565_GET_COLOR_B(solid_colour) != 0)
    //     {
    //         transparency[2] = (float)RGB565_GET_COLOR_B(color) / RGB565_GET_COLOR_B(solid_colour);
    //     }
    // }

    // if (color == 0xF800)
    // {
    //     red = 31;
    // }
    // else if (color == 0xF8A2)
    // {
    //     red = 31;
    // }
    // else if (color == 0)
    // {
    //     red = 31;
    // }
    // for(int i = 0; i< 3; i++)
    // {
    //     result_rgb[i] =
    // }
    // red = (int)RGB565_GET_COLOR_R(back) + ((int)RGB565_GET_COLOR_R(solid_colour) - RGB565_GET_COLOR_R(back)) * transparency[0];   // RGB565_GET_COLOR_R(color) / RGB565_GET_COLOR_R(solid_colour);
    // green = (int)RGB565_GET_COLOR_G(back) + ((int)RGB565_GET_COLOR_G(solid_colour) - RGB565_GET_COLOR_G(back)) * transparency[1]; // RGB565_GET_COLOR_G(color) / RGB565_GET_COLOR_G(solid_colour);
    // blue = (int)RGB565_GET_COLOR_B(back) + ((int)RGB565_GET_COLOR_B(solid_colour) - RGB565_GET_COLOR_B(back)) * transparency[2];  // RGB565_GET_COLOR_B(color) / RGB565_GET_COLOR_B(solid_colour);
    // if (red > 31)
    // {
    //     red = 31;
    // }
    // if (green > 63)
    // {
    //     green = 63;
    // }
    // if (blue > 31)
    // {
    //     blue = 31;
    // }
    // uint16_t ret = (red << 11) | (green << 5) | (blue);
    // return ret;
    // if (RGB565_GET_COLOR_R(back) > 15 && RGB565_GET_COLOR_G(back) > 31 && RGB565_GET_COLOR_B(back) > 15)
    // {
    //     uint16_t red = 31 - RGB565_GET_COLOR_R(color) * (31 - RGB565_GET_COLOR_R(solid_colour)) / RGB565_GET_COLOR_R(solid_colour);
    //     uint16_t green = 63 - RGB565_GET_COLOR_G(color) * (63 - RGB565_GET_COLOR_G(solid_colour)) / RGB565_GET_COLOR_G(solid_colour);
    //     uint16_t blue = 31 - RGB565_GET_COLOR_B(color) * (31 - RGB565_GET_COLOR_B(solid_colour)) / RGB565_GET_COLOR_B(solid_colour);
    //     if (blue > 31)
    //     {
    //         blue = 31;
    //     }
    //     if (green > 63)
    //     {
    //         green = 63;
    //     }
    //     if (red > 31)
    //     {
    //         red = 31;
    //     }
    //     uint16_t new_color = (red << 11) | (green << 5) | (blue);
    //     return get_multiply_color(back, new_color);
    //     // return new_color;
    //     //白底
    //     // red = RGB565_GET_COLOR_B(back) * RGB565_GET_COLOR_B(color) / 31 + transparency_red*RGB565_GET_COLOR_R(color);
    //     // green = RGB565_GET_COLOR_B(back) * RGB565_GET_COLOR_B(color) / 31 +;
    //     // blue = RGB565_GET_COLOR_B(back) * RGB565_GET_COLOR_B(color) / 31 + ;
    //     // return back;
    // }
    // else
    // {
    //     //黑底
    //     return get_filter_color(color, back);
    //     // red = transparency_red * RGB565_GET_COLOR_R(solid_colour);
    // }
}
static uint16_t get_multiply_color(uint16_t color1, uint16_t color2)
{
    if (color1 == 0xffdf)
    {
        color1 = 0xffff;
    }
    uint16_t red = 0;
    uint16_t green = 0;
    uint16_t blue = 0;
    red = RGB565_GET_COLOR_R(color1) * RGB565_GET_COLOR_R(color2) / 31;
    green = RGB565_GET_COLOR_G(color1) * RGB565_GET_COLOR_G(color2) / 63;
    blue = RGB565_GET_COLOR_B(color1) * RGB565_GET_COLOR_B(color2) / 31;
    if (blue > 31)
    {
        blue = 31;
    }
    if (green > 63)
    {
        green = 63;
    }
    if (red > 31)
    {
        red = 31;
    }
    uint16_t ret = (red << 11) | (green << 5) | (blue);
    return ret;
}
void draw_on_chip_unzip_gradients_image_with_back_ground(int x, int y, uint8_t const *const binary_image, uint16_t forecolor, uint16_t backcolor_start, uint16_t backcolor_end)
{
    int w = 0;
    int h = 0;
    int img_x_index = 0;
    int img_y_index = 0;
    uint16_t color = 0;
    if (binary_image == 0)
    {
        w = OLED_SIZE_X;
        h = OLED_SIZE_Y;
    }
    else
    {
        w = binary_image[0];
        h = binary_image[1];
    }
    int draw_y = 0;
    for (img_y_index = 0; img_y_index < h; img_y_index++)
    {
        draw_y = y + img_y_index;
        if ((draw_y >= disp_ctrl.area_start_y) && (draw_y <= disp_ctrl.area_end_y))
        {
            for (img_x_index = 0; img_x_index < w; img_x_index++)
            {
                if (binary_image == NULL)
                {
                    color = get_gradients(backcolor_start, backcolor_end, img_y_index, h);
                    draw_point(x + img_x_index, y + img_y_index, color);
                }
                else if (binary_image[2 + img_y_index / 8 * w + img_x_index] & (0x80 >> (img_y_index % 8)))
                {
                    draw_point(x + img_x_index, y + img_y_index, forecolor);
                }
                else
                {
                    color = get_gradients(backcolor_start, backcolor_end, img_y_index, h);
                    draw_point(x + img_x_index, y + img_y_index, color);
                }
            }
        }
    }
}

int draw_off_chip_string_calculate(int x1, int y1, int x2, int y2, uint16_t const *unicode_str, uint16_t reserve_size)
{
    uint8_t width = 0;
    uint16_t const *unicode_str_in = unicode_str;
    uint8_t invalid_flag = 0;
    uint8_t x_start = x1;
    uint16_t disp_width = 0;

    extern_font16_char_info_t font_temp;
    if (extern_font_is_valid() == false) //假如字库打不开不显示
    {
        return 0;
    }

    while (*unicode_str_in != '\0')
    {
        if (*unicode_str_in < 0x20) //特殊意义符号
        {
            if (*unicode_str_in == '\x0A') //换行符
            {
                unicode_str_in++;
                x1 = x_start;
                y1 += FONT16_SIZE + FONT_SIZE_VERTICAL_INTERVAL; // 16x16的显示每次跳2行
                if (y1 >= (y2 - FONT16_SIZE))
                {
                    break;
                }
            }
            else //其他特殊字符跳过（包括回车0x0d等）
            {
                unicode_str_in++;
            }
            continue;
        }

        extern_font16_get_bit_map(*unicode_str_in, &font_temp);
        width = font_temp.width;

        if (width == 0)
        {
            if (invalid_flag) //处理方框不连续,跳过不显示
            {
                unicode_str_in++;
                continue;
            }
            else
            {
                // 遇到字库不存在的字符，显示"口"
                width = 16;
                invalid_flag = 1;
            }
        }
        else
        {
            invalid_flag = 0;
        }

        if (y1 >= (y2 - FONT16_SIZE * 2)) //末行需要预留空间
        {
            if ((width + x1) > x2 - reserve_size)
            {
                break; //显示溢出
            }
        }
        else if ((width + x1) > x2)
        {
            x1 = x_start;
            y1 += FONT16_SIZE + FONT_SIZE_VERTICAL_INTERVAL; // 16x16的显示每次跳2行
        }
        x1 += width + FONT_SIZE_HORIZ_INTERVAL;
        disp_width += width + FONT_SIZE_HORIZ_INTERVAL;
        unicode_str_in++;
    }

    return ((uint8_t *)unicode_str_in - (uint8_t *)unicode_str) | (disp_width << 16);
}
uint32_t draw_off_chip_string(int x1, int y1, int x2, int y2, uint16_t const *unicode_str, uint16_t reserve_size, int16_t *align_type)
{
    uint8_t *dot_buff = 0;
    int width = 0;
    uint16_t const *unicode_str_in = 0;
    uint16_t const *unicode_str_finish = 0;

    uint16_t *p_disp_buff = 0; //指向要填充的位置
    uint8_t invalid_flag = 0;
    int x_start = 0;
    uint8_t valid_line_flag = 0; //标记当前解析的行和刷新的区域有没有重合区域，不重合则跳过
    int icon_start_y = 0;
    int icon_end_y = 0; //标记ICON需要显示的范围
    uint16_t over_y = 0;

    //#warning "倒着刷有问题,需要改为统一一次计算分开索引"
    if ((disp_ctrl.area_end_y < y1) || (*unicode_str == '\0'))
    {
        return 0;
    }

    unicode_str_in = unicode_str;
    unicode_str_finish = unicode_str;
    invalid_flag = 0;
    x_start = x1;
    over_y = 0;

    extern_font16_char_info_t font_temp;
    if (extern_font_is_valid() == false) //假如字库打不开不显示
    {
        return 0;
    }
    dot_buff = font_temp.data;

    if (y1 >= disp_ctrl.area_start_y)
    {
        p_disp_buff = disp_ctrl.disp_buff[disp_ctrl.p_buff_flag] + (y1 - disp_ctrl.area_start_y) * OLED_SIZE_X; //指向要填充的位置
        icon_start_y = 0;
    }
    else
    {
        p_disp_buff = disp_ctrl.disp_buff[disp_ctrl.p_buff_flag]; //指向要填充的位置
        icon_start_y = disp_ctrl.area_start_y - y1;
    }
    if (disp_ctrl.area_end_y >= (y1 + FONT16_SIZE - 1))
    {
        icon_end_y = FONT16_SIZE - 1;
    }
    else
    {
        icon_end_y = disp_ctrl.area_end_y - y1;
    }
    valid_line_flag = (disp_ctrl.area_start_y < (y1 + FONT16_SIZE)); //判断和要显示的区域是否有重叠区域
    uint16_t last_code = 0;
    while (*unicode_str_in != '\0')
    {
        if (last_code == '\x0A')
        {
            *align_type = get_string_align_type(unicode_str_in);
        }
        last_code = *unicode_str_in;
        if (*unicode_str_in < 0x20) //特殊意义符号
        {
            if (*unicode_str_in == '\x0A') //换行符
            {
                unicode_str_in++;
                x1 = x_start;
                y1 += FONT16_SIZE + FONT_SIZE_VERTICAL_INTERVAL; // 16x16的显示每次跳2行
                if (y1 >= (y2 - FONT16_SIZE))
                {
                    break;
                }
                if (disp_ctrl.area_end_y < y1)
                {
                    if (disp_ctrl.area_end_y == (y1 - 1))
                    {
                        unicode_str_finish = unicode_str_in;
                        over_y++;
                    }
                    break;
                }
                if (y1 >= disp_ctrl.area_start_y)
                {
                    p_disp_buff = disp_ctrl.disp_buff[disp_ctrl.p_buff_flag] + (y1 - disp_ctrl.area_start_y) * OLED_SIZE_X; //指向要填充的位置
                    icon_start_y = 0;
                }
                else
                {
                    p_disp_buff = disp_ctrl.disp_buff[disp_ctrl.p_buff_flag]; //指向要填充的位置
                    icon_start_y = disp_ctrl.area_start_y - y1;
                }
                if (disp_ctrl.area_end_y >= (y1 + FONT16_SIZE - 1))
                {
                    icon_end_y = FONT16_SIZE - 1;
                }
                else
                {
                    icon_end_y = disp_ctrl.area_end_y - y1;
                }
                unicode_str_finish = unicode_str_in;
                over_y++;
                valid_line_flag = (disp_ctrl.area_start_y < (y1 + FONT16_SIZE)); //判断和要显示的区域是否有重叠区域
            }
            else //其他特殊字符跳过（包括回车0x0d等）
            {
                unicode_str_in++;
            }
            continue;
        }
        //增加空格的处理，一个2006-强转为空格-某个软件消息推送的空格是这个字符
        if ((*unicode_str_in == 0x20) || ((*unicode_str_in >= 0x2000) && (*unicode_str_in <= 0x200F)))
        {
            width = FONT16_SIZE / 2;
            memset(font_temp.data, 0, sizeof(font_temp.data));
        }
        else
        {
            extern_font16_get_bit_map(*unicode_str_in, &font_temp);
            width = font_temp.width;
        }
        if (width == 0)
        {
            // DISP_LOG("width == 0,utf8_len=%d",utf8_len);
            if (invalid_flag) //处理方框不连续,跳过不显示
            {
                ++unicode_str_in;
                continue;
            }
            else
            {
                // 遇到字库不存在的字符，显示"口"
                memcpy(dot_buff, ICON_FONT_LIB_UNDEFINE, 32);
                width = 16;
                invalid_flag = 1;
            }
        }
        else
        {
            invalid_flag = 0;
        }

        if (y1 > (y2 - FONT16_SIZE * 2)) //末行需要预留空间
        {
            if ((width + x1) > x2 - reserve_size)
            {
                break; //显示溢出
            }
        }
        else if ((width + x1) > x2)
        {
            x1 = x_start;
            y1 += FONT16_SIZE + FONT_SIZE_VERTICAL_INTERVAL; // 16x16的显示每次跳2行
            if (y1 >= (y2 - FONT16_SIZE))
            {
                break;
            }
            if (disp_ctrl.area_end_y < y1)
            {
                if (disp_ctrl.area_end_y == (y1 - 1))
                {
                    unicode_str_finish = unicode_str_in;
                    over_y++;
                }
                break;
            }
            if (y1 >= disp_ctrl.area_start_y)
            {
                p_disp_buff = disp_ctrl.disp_buff[disp_ctrl.p_buff_flag] + (y1 - disp_ctrl.area_start_y) * OLED_SIZE_X; //指向要填充的位置
                icon_start_y = 0;
            }
            else
            {
                p_disp_buff = disp_ctrl.disp_buff[disp_ctrl.p_buff_flag]; //指向要填充的位置
                icon_start_y = disp_ctrl.area_start_y - y1;
            }
            if (disp_ctrl.area_end_y >= (y1 + FONT16_SIZE - 1))
            {
                icon_end_y = FONT16_SIZE - 1;
            }
            else
            {
                icon_end_y = disp_ctrl.area_end_y - y1;
            }
            unicode_str_finish = unicode_str_in;
            over_y++;
            valid_line_flag = (disp_ctrl.area_start_y < (y1 + FONT16_SIZE)); //判断和要显示的区域是否有重叠区域
        }
        if (valid_line_flag)
        {
            uint16_t *p_disp_temp = 0;
            if (*align_type == align_type_right)
            {
                p_disp_temp = p_disp_buff + x1;
            }
            else
            {
                int offset = x1 - x_start;
                p_disp_temp = p_disp_buff + x2 - offset - width;
            }
            //展开16*16字体
            if (icon_start_y < 8) //第一行
            {
                uint8_t b = icon_end_y > 7 ? 7 : icon_end_y;
                for (uint8_t a = icon_start_y; a <= b; a++)
                {
                    uint8_t offset = 1 << a;
                    for (uint8_t i = 0; i < width; i++)
                    {
                        if (dot_buff[i] & offset)
                        {
                            p_disp_temp[i] = RGB565_COLOR_WHITE;
                        }
                    }
                    p_disp_temp += OLED_SIZE_X;
                }
            }
            if ((icon_start_y < 16) & (icon_end_y >= 8)) //第二行
            {
                uint8_t b = icon_end_y > 15 ? 15 : icon_end_y;
                for (uint8_t a = icon_start_y > 8 ? icon_start_y : 8; a <= b; a++)
                {
                    uint8_t offset = 1 << (a - 8);
                    for (uint8_t i = 0; i < width; i++)
                    {
                        if (dot_buff[i + FONT16_SIZE] & offset)
                        {
                            p_disp_temp[i] = RGB565_COLOR_WHITE;
                        }
                    }
                    p_disp_temp += OLED_SIZE_X;
                }
            }
            if (icon_end_y >= 16) //第三行
            {
                for (uint8_t a = icon_start_y > 16 ? icon_start_y : 16; a <= icon_end_y; a++)
                {
                    uint8_t offset = 1 << (a - 16);
                    for (uint8_t i = 0; i < width; i++)
                    {
                        if (dot_buff[i + FONT16_SIZE * 2] & offset)
                        {
                            p_disp_temp[i] = RGB565_COLOR_WHITE;
                        }
                    }
                    p_disp_temp += OLED_SIZE_X;
                }
            }
        }
        x1 += width + FONT_SIZE_HORIZ_INTERVAL;
        unicode_str_in++;
    }
    if ((*unicode_str_in == '\0') && (icon_end_y >= (FONT16_SIZE - 1))) //显示完成
    {
        unicode_str_finish = unicode_str_in;
    }

    return ((uint8_t *)unicode_str_finish - (uint8_t *)unicode_str) | (over_y << 16);
}
void draw_on_chip_unzip_image_rotate(const unsigned char *p_image, uint16_t ignore_color, uint32_t centre_xy, uint32_t centre_set_xy, uint16_t degree, int solid_colour, bool transparency_by_white)
{
    uint16_t *pSrc = (uint16_t *)(p_image + 4);
    int16_t img_w = p_image[1] << 8 | p_image[0];
    int16_t img_h = p_image[3] << 8 | p_image[2];

    int16_t x0 = img_w / 2; //默认x轴在中点
    int16_t y0 = centre_xy & 0xFFFF;

    float angle = degree * PI / 180.f; //旋转角度
    float co = cos(angle);             //余弦
    float si = sin(angle);             //正弦
    int rotateW, rotateH;              //旋转后图像的高宽

    int xMin, xMax, yMin, yMax;
    int xOff, yOff; //偏移
    float xSrc = 0.;
    float ySrc = 0.; //变换后图像的坐标在原图中的坐标

    //临时变量
    uint16_t a1, a2, a3, a4;

    //计算旋转后的坐标范围
    rotateH = img_w * fabs(si) + img_h * fabs(co);
    rotateW = img_w * fabs(co) + img_h * fabs(si);

    //计算偏移
    xOff = (centre_set_xy >> 16) - x0;
    yOff = (centre_set_xy & 0xFFFF) - y0;
    yMin = y0 - (y0 - img_h / 2) * co - rotateH / 2;
    yMax = yMin + rotateH + 1; //加1

    //判断和要显示的区域是否有重叠区域
    if ((disp_ctrl.area_start_y > (yMax + yOff)) || (disp_ctrl.area_end_y < yMin + yOff))
    {
        return;
    }

    xMin = x0 + (y0 - img_h / 2) * si - rotateW / 2; //  (y0*si + (img_w-x0)*co-rotateW);
    xMax = xMin + rotateW + 1;

    uint16_t *p_disp_buff;
    if ((yMin + yOff) >= disp_ctrl.area_start_y)
    {
        p_disp_buff = disp_ctrl.disp_buff[disp_ctrl.p_buff_flag] + ((yMin + yOff) - disp_ctrl.area_start_y) * OLED_SIZE_X + xOff; //指向要填充的位置
    }
    else
    {
        p_disp_buff = disp_ctrl.disp_buff[disp_ctrl.p_buff_flag] + xOff; //指向要填充的位置
        yMin = disp_ctrl.area_start_y - yOff;
    }
    if (yMax > (disp_ctrl.area_end_y - yOff))
    {
        yMax = disp_ctrl.area_end_y - yOff;
    }

    for (int y = yMin; y <= yMax; y++)
    {
        for (int x = xMin; x <= xMax; x++)
        {
            //求取在原图中的坐标
            xSrc = co * (float)(x - img_w / 2) - si * (float)(y0 - y) + (float)((int)(img_w / 2));
            ySrc = si * (float)(img_w / 2 - x) + co * (float)(y - y0) + (float)((int)(y0));

            //如果在原图范围内
            if (ySrc >= 0.f && ySrc < img_h - 0.5f && xSrc >= 0.f && xSrc < img_w - 0.5f)
            {
                int xSmall = (int)xSrc;
                int xBig = (int)(xSrc + 0.99999f);
                int ySmall = (int)(ySrc);
                int yBig = (int)(ySrc + 0.99999f);
                a1 = (pSrc[ySmall * img_w + xSmall]);
                a2 = (pSrc[ySmall * img_w + xBig]);
                a3 = (pSrc[yBig * img_w + xSmall]);
                a4 = (pSrc[yBig * img_w + xBig]);
                float ux = xSrc - xSmall;
                float uy = ySrc - ySmall;

                //双线性插值
                float f1, f2, f3, f4;
                f1 = (1 - ux) * (1 - uy);
                f2 = (1 - ux) * uy;
                f3 = (1 - uy) * ux;
                f4 = ux * uy;
                float r = f1 * RGB565_GET_COLOR_R(a1) + f2 * RGB565_GET_COLOR_R(a3) + f3 * RGB565_GET_COLOR_R(a2) + f4 * RGB565_GET_COLOR_R(a4);
                float g = f1 * RGB565_GET_COLOR_G(a1) + f2 * RGB565_GET_COLOR_G(a3) + f3 * RGB565_GET_COLOR_G(a2) + f4 * RGB565_GET_COLOR_G(a4);
                float b = f1 * RGB565_GET_COLOR_B(a1) + f2 * RGB565_GET_COLOR_B(a3) + f3 * RGB565_GET_COLOR_B(a2) + f4 * RGB565_GET_COLOR_B(a4);
                //描点
                uint16_t temp_color = ((uint8_t)r << 11) | ((uint8_t)g << 5) | (uint8_t)b;
                // p_disp_buff[x] = temp_color;
                if (solid_colour == -1)
                {
                    p_disp_buff[x] = get_filter_color(temp_color, p_disp_buff[x]);
                }
                else if (solid_colour == -2)
                {
                    p_disp_buff[x] = get_multiply_color(temp_color, p_disp_buff[x]);
                }
                else
                {
                    p_disp_buff[x] = transparency_anti_aliasing(temp_color, p_disp_buff[x], solid_colour, transparency_by_white);
                }

                // if ((r < 12) && (g < 24) && (b < 12))
                // {
                //     p_disp_buff[x] = get_color_mixture3(temp_color, p_disp_buff[x]);
                // }
                // else
                // {
                //     p_disp_buff[x] = temp_color;
                // }
                // if (ignore_color != temp_color)
                // {
                //     //p_disp_buff[x] = get_color_mixture3(temp_color, p_disp_buff[x]);
                // }
            }
        }
        p_disp_buff += OLED_SIZE_X;
    }
}
